<?php
/**
 * 
 * @author Youssef Driouach
 *
 */
class Application_Model_OfferMapper{

	protected $_dbTable;

	public function setDbTable($dbTable)
	{
		if (is_string($dbTable)) {
			$dbTable = new $dbTable();
		}
		if (!$dbTable instanceof Zend_Db_Table_Abstract) {
			throw new Exception('Invalid table data gateway provided');
		}
		$this->_dbTable = $dbTable;
		return $this;
	}

	public function getDbTable()
	{
		if (null === $this->_dbTable) {
			$this->setDbTable('Application_Model_DbTable_Offer');
		}
		return $this->_dbTable;
	}
	
	/**
	 * save or update an offer in the data base 
	 * 
	 * @param Application_Model_Offer $offer
	 * @return Ambigous <mixed, multitype:>
	 */
	public function save(Application_Model_Offer $offer)
	{
		
		$data = array(
				'id_user'   	=> $offer->getUser()->getUserId(),
				'id_object'		=> $offer->getObject()->getObjectId(),
				'classe'		=> $offer->getClasse(),
				'id_classe'		=> $offer->getId_classe(),
				'price' 		=> $offer->getPrice(),
				'priceCurrency' => $offer->getPrice_currency(),
				'avalability'	=> $offer->getAvalability(),
				'status'		=> $offer->getStatus(),
				'startDate'		=> $offer->getStart_date(),
				'endDate'		=> $offer->getEnd_date(),
				'description'	=> $offer->getDescription(),
		);
	
		$where = array( 'id_object = ?' => $offer->getObject()->getObjectId(),
						'id_user = ?'	=> $offer->getUser()->getUserId());
		
		$row = new Zend_Db_Table_Row();
		$row = $this->getDbTable()->fetchRow($where);
		if($row == null)
		{
			unset($data['id_offer']);
			$id_offer =  $this->getDbTable()->insert($data);
			//@TODO verifier pour décommenter ce bout de code
			//Add addresses
// 			foreach($offer->getAddresses() as $addresse){
// 				$addressmapper = new Application_Model_AddressMapper();
// 				$id_address = $addressmapper->save($addresse);
			
// 				$assocValues = array(
// 						'addressId'	=> $id_address,
// 						'offerId'	=> $id_offer,
// 				);
// 				$assocOA = new Application_Model_AssocOffrAddr($assocValues);
// 				$assocOAMapper = new Application_Model_AssocOffrAddrMapper();
// 				$assocOAMapper->save($assocOA);
// 			}
			
			return $id_offer;
		}else{
			$this->getDbTable()->update($data, $where);
			$id_offer = $row->save();
			//Add addresses
			foreach($offer->getAddresses() as $addresse){
				$addressmapper = new Application_Model_AddressMapper();
				$id_address = $addressmapper->save($addresse);
					
				$assocValues = array(
						'addressId'	=> $id_address,
						'offerId'	=> $id_offer,
				);
				$assocOA = new Application_Model_AssocOffrAddr($assocValues);
				$assocOAMapper = new Application_Model_AssocOffrAddrMapper();
				$assocOAMapper->save($assocOA);
			}
			
			return $id_offer;
		}
		
	}
	
	/**
	 * find offer on the data base by offer identifiant 
	 * @param unknown_type $id
	 * @param Application_Model_Offer $offer
	 * @return void|Application_Model_Offer
	 */
	public function find($id, Application_Model_Offer $offer)
	{
		$assocOffrAddrMapper = new Application_Model_AssocOffrAddrMapper();
		$result = $this->getDbTable()->find($id);
		if (0 == count($result)) {
			return;
		}
		$row = $result->current();
		$offer->setOfferId($row->id_offer);
		$offer->setAvalability($row->avalability);
		$offer->setEnd_date($row->endDate);
		$offer->setPrice($row->price);
		$offer->setPrice_currency($row->priceCurrency);
		$offer->setStart_date($row->startDate);
		$offer->setStatus($row->status);
		$offer->setDescription($row->description);
		$offer->setClasse($row->classe);
		$offer->setId_classe($row->id_classe);
		
		//@TODO
		//add a try catch for the object
		$object = Application_Model_Factory_ObjectMapperFactory::find($row->id_classe, $row->classe);
		$offer->setObject($object);
		
		$userMapper = new Application_Model_UserMapper();
		$user = $userMapper->find($row->id_user);
		$offer->setUser($user);
		$offer->setAddresses($assocOffrAddrMapper->findAddresses($row->id_offer));
		
		return $offer;
	}
	
	/**
	 * find the offer in the database and return one offer or null
	 * @param unknown_type $where
	 * @return NULL|Application_Model_Offer
	 */
	public function findWhere($where)
	{
		$assocOffrAddrMapper = new Application_Model_AssocOffrAddrMapper();
		$row = $this->getDbTable()->fetchRow($where);
		if (0 == count($row)) {
			return null;
		}
		
		$offer = new Application_Model_Offer();
		$offer->setOfferId($row->id_offer);
		$offer->setAvalability($row->avalability);
		$offer->setEnd_date($row->endDate);
		$offer->setPrice($row->price);
		$offer->setPrice_currency($row->priceCurrency);
		$offer->setStart_date($row->startDate);
		$offer->setStatus($row->status);
		$offer->setDescription($row->description);
		$offer->setClasse($row->classe);
		$offer->setId_classe($row->id_classe);
		
		//@TODO
		//add a try catch for the object
		$object = Application_Model_Factory_ObjectMapperFactory::find($row->id_classe, $row->classe);
		$offer->setObject($object);
		
		$userMapper = new Application_Model_UserMapper();
		$user = $userMapper->find($row->id_user);
		$offer->setUser($user);
		$offer->setAddresses($assocOffrAddrMapper->findAddresses($row->id_offer));
		
		return $offer;
	}
	
	public function fetchAll($where, $order = null, $count = null, $offset = null){
		$rows = $this->getDbTable()->fetchAll($where,$order,$count,$offset);
		if (0 == count($rows)) {
			return null;
		}
		$offers = array();
		foreach ($rows as $row){
			$offer = $this->offerBuilder(array('id_offer = ?' => $row->id_offer));
			$offers[] = $offer;
		}
		
		return $offers;
	}
	
	/**
	 * verify if the Offer is not yet specified if it is a sale or a rent
	 * @param unknown_type $where
	 * @return boolean
	 */
	public function isEmptyOffer($where)
	{
		$saleMapper = new Application_Model_SaleMapper();
		$rentMapper = new Application_Model_RentMapper();
		if($saleMapper->findWhere($where) == null && $rentMapper->findWhere($where) == null)
			return true;
		else
			return false;
	}
	/**
	 * build an offer from the offer identifiant
	 * $where always contain the id_offer
	 * @param unknown_type $where
	 * @return instante of Application_Model_Offer or null
	 */
	public function offerBuilder($where)
	{
		$offerMapper = new Application_Model_OfferMapper();
		if(!$this->isEmptyOffer($where))
		{
			$saleMapper = new Application_Model_SaleMapper();
			$rentMapper = new Application_Model_RentMapper();
			$sale = $saleMapper->findWhere($where);
			$rent = $rentMapper->findWhere($where);
			if($sale != null)
			{
				return $saleMapper->find($sale->getSaleId(), new Application_Model_Sale());
			}
			if($rent != null)
			{
				return $rentMapper->find($rent->getRentId(), new Application_Model_Rent());
			}
			
		}else{
			$row = $this->getDbTable()->fetchRow($where);
			if (0 == count($row)) {
				return null;
			}
			
			$whereobject = array('id_object = ?' 	=> $row->id_object);
			//var_dump($whereobject);
			$offer = $offerMapper->findWhere($whereobject);
			
			if($offer != null)
				return $offer;
		}
	}
	
	/**
	 * delete an offer from the data base 
	 * @param unknown_type $id
	 */
	public function delete($id)
	{
		$result = $this->getDbTable()->find($id);
		if (0 != count($result)) {
			$offraddr = new Application_Model_AssocOffrAddrMapper();
			$offraddr->delete(array('id_offer = ?' => $id));
			$this->getDbTable()->delete(array('id_offer = ?' => $id));
		}
	
	}
	
	public function deleteOfferOnly($id)
	{
		$result = $this->getDbTable()->find($id);
		if (0 != count($result)) {
			$offraddr = new Application_Model_AssocOffrAddrMapper();
			$offraddr->delete(array('id_offer = ?' => $id));
			$data = array(
					
					'price' 		=> null,
					'priceCurrency' => null,
					'avalability'	=> null,
					'status'		=> null,
					'startDate'		=> null,
					'endDate'		=> null,
					'description'	=> null,
			);
			$where = array( 'id_offer = ?' => $id);
			$this->getDbTable()->update($data, $where);
		}
	
	}
	public function indexBuilder(Zend_Search_Lucene_Document $doc, Application_Model_Offer $offer)
	{
		$requestBuilder = new Application_Model_Builder_Request();
		$doc->addField(Zend_Search_Lucene_Field::Text('offerId', $offer->getOfferId(), 'utf-8'));
		$doc->addField(Zend_Search_Lucene_Field::Text('dateCreation', date('Y-m-d H:i:s'), 'utf-8'));
		$doc->addField(Zend_Search_Lucene_Field::Text('offerDescription', $offer->getDescription(), 'utf-8'));
		$doc->addField(Zend_Search_Lucene_Field::Text('end_date', $offer->getEnd_date(), 'utf-8'));
		$doc->addField(Zend_Search_Lucene_Field::Text('start_date', $offer->getStart_date(), 'utf-8'));
		$doc->addField(Zend_Search_Lucene_Field::Text('price_currency', $offer->getPrice_currency(), 'utf-8'));
		$doc->addField(Zend_Search_Lucene_Field::Text('price', $requestBuilder->adjustfloat(9, $offer->getPrice(), '0'), 'utf-8'));
		$doc->addField(Zend_Search_Lucene_Field::Text('userId', $offer->getUser()->getUserId(), 'utf-8'));
		
		return $doc;
	}
	
}